package com.apa7.keepaccounts.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.apa7.keepaccounts.dao.ConfigDao;
import com.apa7.keepaccounts.dao.PayModeDao;
import com.apa7.keepaccounts.dao.PayTypeDao;
import com.apa7.keepaccounts.dao.UserDao;
import com.apa7.keepaccounts.dto.GetUserInfoRequest;
import com.apa7.keepaccounts.dto.ReturnData;
import com.apa7.keepaccounts.dto.WxUserInfo;
import com.apa7.keepaccounts.entity.Config;
import com.apa7.keepaccounts.entity.PayMode;
import com.apa7.keepaccounts.entity.PayType;
import com.apa7.keepaccounts.entity.User;
import com.apa7.keepaccounts.service.LoginService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import okhttp3.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

@Service
public class LoginImpl implements LoginService{

    @Autowired
    private ConfigDao configDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private PayTypeDao payTypeDao;
    @Autowired
    private PayModeDao payModeDao;
    @Value("${wx.auth.get-access-token-url}")
    private String getAccessTokenUrl;

    private static Logger logger = LoggerFactory.getLogger(LoginImpl.class);

    /**
     * 登录是否过期
     *
     * @param key 登录凭证
     * @return boolean
     */
    @Override
    public boolean isLogin(String key) {
        /*QueryWrapper<User> qw=new QueryWrapper<>();
        qw.lambda().eq(User::getKey, key);
        User user=userDao.selectOne(qw);

        Long time= System.currentTimeMillis()/1000;
        if(user.getKeyTime()<time){
            return false;
        }

        return true;*/
        return false;
    }

    /**
     * 注册一个匿名用户
     *
     * @return User
     */
    @Override
    public User registerAnonymous() {
        //查出支出类型和支付方式
        List<PayMode> payModes=payModeDao.selectList(null);
        List<PayType> payTypes=payTypeDao.selectList(null);

        //添加数据
        User user=new User();
        user.setOpenId("");
        user.setWxName("");
        user.setWxImg("");
        user.setWxInfo("");
        user.setTime(System.currentTimeMillis()/1000);
        user.setPayMode(JSONObject.toJSONString(payModes));
        user.setPayType(JSONObject.toJSONString(payTypes));
        user.setIsAnonymous(1);
        //key值
        long time=System.currentTimeMillis();
        long math=(long) ((Math.random()*9+1)*10000);
        String key= DigestUtils.md5Hex(time +String.valueOf(math));
        user.setLoginKey(key);
        userDao.insert(user);

        return user;
    }

    /**
     * 添加或者更新一个用户
     *
     * @param code String
     * @return key
     */
    @Override
    public String setUserInfo(String code, JSONObject jsonObject) {
        //从数据库获取请求信息
        Config config=configDao.selectById(1);

        //使用okhttp3请求微信服务器换取解密key
        OkHttpClient okHttpClient = new OkHttpClient();
        String param = getAccessTokenUrl + "?" + "appid=" + config.getAppId() + '&' +
                "secret=" + config.getAppSecret() + '&' +
                "js_code=" + code + '&' +
                "grant_type=authorization_code";

        Request request = new Request.Builder()
                .url(param)
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            String AccessTokenResultJson=call.execute().body().string();
            JSONObject AccessTokenResult= JSON.parseObject(AccessTokenResultJson);
            System.out.println(AccessTokenResultJson);
            if(AccessTokenResult.getIntValue("errcode")!=0){
                logger.info("获取accessToken失败！");
                logger.info("错误码："+AccessTokenResult.getString("errcode"));
                logger.info("错误信息:"+AccessTokenResult.getString("errmsg"));
                return "";
            }

            /* !解密！！！由于已经拿到了openid就暂时不解密了! */
            //更具openid获取信息
            String openId=AccessTokenResult.getString("openid");
            QueryWrapper<User> qw=new QueryWrapper<>();
            qw.lambda().eq(User::getOpenId,openId);
            User user=userDao.selectOne(qw);

            //获取用户信息
            WxUserInfo userInfo = JSONObject.parseObject(jsonObject.getString("userInfo"), WxUserInfo.class);
            if(userInfo==null){
                return null;
            }

            //填充user信息
            User userList=new User();
            userList.setOpenId(openId);
            userList.setWxName(userInfo.getNickName());
            userList.setWxImg(userInfo.getAvatarUrl());
            userList.setWxInfo(JSONObject.toJSONString(jsonObject.getString("userInfo")));
            //key值
            long time=System.currentTimeMillis();
            long math=(long) ((Math.random()*9+1)*10000);
            String key= DigestUtils.md5Hex(time +String.valueOf(math));
            userList.setLoginKey(key);

            //判断是否注册过
            if(user==null||user.getUserId()==0){
                //没有注册过
                //获取支付方式和支出类型
                List<PayMode> payModes=payModeDao.selectList(null);
                List<PayType> payTypes=payTypeDao.selectList(null);
                userList.setPayMode(JSONObject.toJSONString(payModes));
                userList.setPayType(JSONObject.toJSONString(payTypes));
                userList.setTime(System.currentTimeMillis()/1000);
                userList.setIsAnonymous(0);

                //添加
                userDao.insert(userList);
                return userList.getLoginKey();
            }else{
                //注册过
                userList.setUserId(user.getUserId());
                userDao.updateById(userList);
                return userList.getLoginKey();
            }

        }catch (IOException e) {
            logger.error("-----系统发生错误-----");
            logger.error("错误信息:"+e.getMessage());
            logger.error("原信息:"+JSON.toJSONString(e));
            logger.error("---------------------");
            return null;
        }
    }


}
